package com.awesome.common.base.mvvm

import android.os.Looper
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer


/**
 * Author: JFangZ
 * Email:  janezhang1901@163.com
 * Date:2021/5/19 15:55
 * Description:包含(开始,错误,正确状态)的LiveData
 */
class StateLiveData<T> : MutableLiveData<T>() {
    /**
     * 数据状态
     * 记录数据上一次的状态
     */
    private val liveDataStatus by lazy { MutableLiveData<LiveDataStatus>() }


    /**
     * 数据改变前
     */
    fun setStart() {
        changeStatus(LiveDataStatus.START)
    }

    /**
     * 数据改变成功
     */
    fun setSuccess(value: T) {
        if (isMainThread()) {
            setValue(value)
        } else {
            postValue(value)
        }
        changeStatus(LiveDataStatus.SUCCESS)
    }

    /**
     * 数据改变出现错误
     * @param msg 一些错误描述信息
     */
    fun setError(code: Int = -1, msg: String = "") {
        changeStatus(LiveDataStatus.ERROR.setMessage(code, msg))
    }

    /**
     * 修改状态 进行判断防止多次观察重复相应
     */
    private fun changeStatus(liveData: LiveDataStatus) {
        if (isMainThread()) {
            liveDataStatus.value = liveData
        } else {
            liveDataStatus.postValue(liveData)
        }
    }

    fun observe(owner: LifecycleOwner, onStart: () -> Unit = {}, onSuccess: (T) -> Unit = {}, onError: (code: Int, msg: String) -> Unit = { code, msg -> }) {
        liveDataStatus.observe(owner, Observer {
            when (it) {
                LiveDataStatus.START -> onStart.invoke()
                LiveDataStatus.SUCCESS -> onSuccess.invoke(value!!)
                LiveDataStatus.ERROR -> onError.invoke(it.state.code, it.state.msg)
            }
        })
    }

    fun observeForever(onStart: () -> Unit = {}, onSuccess: (T?) -> Unit = {}, onError: (code: Int, msg: String) -> Unit = { code, msg -> }) {
        liveDataStatus.observeForever(Observer {
            when (it) {
                LiveDataStatus.START -> onStart.invoke()
                LiveDataStatus.SUCCESS -> onSuccess.invoke(value)
                LiveDataStatus.ERROR -> onError.invoke(it.state.code, it.state.msg)
            }
        })
    }

    private fun isMainThread(): Boolean {
        return Looper.getMainLooper() === Looper.myLooper()
    }
}
